package extract.knowledge.concept;

import com.thinkaurelius.titan.core.TitanGraph;
import common.model.graph.CommonSchema;
import common.model.graph.ConceptSchema;
import common.model.knowledge.ConceptDoc;
import extract.knowledge.general.BaseTransformer;
import extract.knowledge.general.NodeParser;

import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import java.util.List;

import common.dao.gremlin.TitanGraphDao;
import common.model.knowledge.BaseDoc.IDValuePair;

/**
 * Created by Common on 7/24/16.
 */
@Component
public class ConceptTransformer extends BaseTransformer {
    final Logger logger = LoggerFactory.getLogger(ConceptTransformer.class);


    private TitanGraphDao titandb;
    private TitanGraph graph;
    private ConceptFactory concept_factory;

    @Inject
    public ConceptTransformer(
            TitanGraphDao titandb
    ){

        this.titandb = titandb;
        this.graph = this.titandb.getTitanGraph();
        this.concept_factory = new ConceptFactory(this.graph);
    }

    public boolean addProperties(Vertex concept, ConceptDoc concept_doc){
        /*
        add Property
         */
        logger.debug(" ----->>>>> begin to add properties");
        //String name = concept_doc.getName();
        //this.concept_factory.setNameProperty(concept, name);
        String tag = concept_doc.getTag();
        this.concept_factory.setStringProperty(concept , CommonSchema.Properties.has_tag, tag);
        String url = concept_doc.getUrl();
        this.concept_factory.setStringProperty(concept , CommonSchema.Properties.has_url, url);
        return true;
    }

    public boolean addEdges(Vertex concept, ConceptDoc concept_doc){
        /*
        add Edges
         */
        logger.debug(" ----->>>>> begin to add edges");

        List<IDValuePair> base_classes = concept_doc.getTypes();
        this.concept_factory.setMultiMetaEdge(concept, ConceptSchema.Edges.has_base_class, base_classes);
        logger.debug("added base_classes");

        List<IDValuePair> sub_classes = concept_doc.getSub_classes();
        this.concept_factory.setMultiMetaEdge(concept, ConceptSchema.Edges.has_sub_class,  sub_classes);
        logger.debug("added sub_classes");

        List<IDValuePair> instances = concept_doc.getInstances();
        this.concept_factory.setMultiMetaEdge(concept, ConceptSchema.Edges.has_instance,   instances);
        logger.debug("added instances");

        List<IDValuePair> edge_classes = concept_doc.getProperties();
        this.concept_factory.setMultiMetaEdge(concept, ConceptSchema.Edges.has_edgeclass,  edge_classes);
        logger.debug("added edge_classes");

        List<IDValuePair> domains = concept_doc.getDomains();
        this.concept_factory.setMultiMetaEdge(concept, ConceptSchema.Edges.has_domain   ,  domains);
        logger.debug("added domains");

        List<IDValuePair> related_topics = concept_doc.getRelated_topics();
        this.concept_factory.setMultiMetaEdge(concept, ConceptSchema.Edges.has_relate_topic, related_topics);
        logger.debug("added related_topics");

        return true;

    }



    public boolean transformConcept(ConceptDoc concept_doc){
        logger.debug("[transform concept] concept doc = \n{}", concept_doc.toString());
        String id_node = concept_doc.getId();
        Integer id = NodeParser.parse_id( id_node );
        String  label = NodeParser.parse_label( id_node );
        String name = concept_doc.getName();
        logger.info("[transform concept] lablel = {}, id = {}", label ,id);
        if(id == -1){
            logger.error("invalid id, ignore.");
            return false;
        }

        Vertex concept = this.concept_factory.getOrCreateVertex(id);
        this.concept_factory.setNameProperty(concept, name);
        addProperties(concept, concept_doc);
        addEdges(concept, concept_doc);

        return true;

    }



}
